package com.bird.component.lang.util.paramcheck


import com.bird.component.lang.common.exception.ServiceException
import com.bird.component.lang.common.exception.StatusInfo
import com.bird.component.lang.util.log

open class ParamCheckUtil{
    companion object {
        internal var CHECK_NODE: ThreadLocal<CheckNode> = ThreadLocal()
        /**
         * 获取当前校验CheckNode
         */
        internal fun getCheckNode(): CheckNode? {
            return CHECK_NODE.get()
        }
        /**
         * 设置当前CheckNode
         */
        private fun setCheckNode(checkNode: CheckNode) {
            CHECK_NODE.set(checkNode)
        }
        /**
         * 清空当前CheckNode
         */
        private fun removeCheckNode() {
            CHECK_NODE.remove()
        }
        /**
         * 直接用该方法，进行参数校验
         */
        fun doCheck(
            checkPrefix: String,
            checkApply: ParameterCheckBuilder.() -> ParameterCheckBuilder,
        ) {
            try {
                //设置当前checkNode
                //一个线程不可能同时进行多个校验，多个线程这里的checkNode不是同一个
                val parameterCheckBuilder = ParameterCheckBuilder()
                setCheckNode(
                    CheckNode(modelMap = HashMap(), parameterCheckBuilder = parameterCheckBuilder)
                )
                //执行校验
                val check: String = parameterCheckBuilder.checkApply().check()
                if (check.isNotBlank()) {
                    throw ServiceException(
                        "${
                            if (checkPrefix.isNotBlank()) {
                                "$checkPrefix:"
                            } else {
                                ""
                            }
                        }$check",
                        StatusInfo.PARAM_CHECK_ERROR.status()
                    )
                }
            } finally {
                //清理当前checkNode
                log.debug("清理校验数据")
                removeCheckNode()
            }
        }
    }
}

fun toCheck(checkPrefix: String = "", checkApply: ParameterCheckBuilder.() -> ParameterCheckBuilder) {
    ParamCheckUtil.doCheck(checkPrefix, checkApply)
}


fun main() {
    val int:Int? = null
    toCheck {
        notEmpty("狗", "")
        customize(int) { it?.let { i -> i > 3 } ?: false }.orTip("参数必须大于3")
        customize("3") { it.isBlank() }.orTip("参数必须是空的")
    }
}